package authorization

import (
	"MoSkeleton/config/consts"
	"MoSkeleton/framework/core/dto/response"
	"github.com/gin-gonic/gin"
)

func CheckRolesAny(roles []string, subject AuthSubject) gin.HandlerFunc {
	return func(c *gin.Context) {
		if subject == nil {
			response.ErrorAuthorizationFail(c, "")
			return
		}
		subRoles := subject.GetRoles(c)
		if subRoles.Contains(consts.Role_Admin) {
			c.Next()
			return
		}
		ok := subRoles.ContainsAny(roles...)
		if ok {
			c.Next()
		} else {
			response.ErrorAuthorizationFail(c, "")
		}
	}
}

func CheckRole(role string, subject AuthSubject) gin.HandlerFunc {
	return func(c *gin.Context) {
		if subject == nil {
			response.ErrorAuthorizationFail(c, "")
			return
		}
		subRoles := subject.GetRoles(c)
		if subRoles.Contains(consts.Role_Admin) || subRoles.Contains(role) {
			c.Next()
		} else {
			response.ErrorAuthorizationFail(c, "")
		}
	}
}

func CheckRolesAll(roles []string, subject AuthSubject) gin.HandlerFunc {
	return func(c *gin.Context) {
		if subject == nil {
			response.ErrorAuthorizationFail(c, "")
			return
		}
		subRoles := subject.GetRoles(c)
		if subRoles.Contains(consts.Role_Admin) {
			c.Next()
			return
		}
		ok := subRoles.Contains(roles...)
		if ok {
			c.Next()
		} else {
			response.ErrorAuthorizationFail(c, "")
		}
	}
}

func CheckPermissionsAny(permissions []string, subject AuthSubject) gin.HandlerFunc {
	return func(c *gin.Context) {
		if subject == nil {
			response.ErrorAuthorizationFail(c, "")
			return
		}
		subPermissions := subject.GetPermissions(c)
		if subPermissions.Contains(consts.Permission_All) {
			c.Next()
			return
		}
		ok := subPermissions.ContainsAny(permissions...)
		if ok {
			c.Next()
		} else {
			response.ErrorAuthorizationFail(c, "")
		}
	}
}

func CheckPermissionsAll(permissions []string, subject AuthSubject) gin.HandlerFunc {
	return func(c *gin.Context) {
		if subject == nil {
			response.ErrorAuthorizationFail(c, "")
			return
		}

		subPermissions := subject.GetPermissions(c)
		if subPermissions.Contains(consts.Permission_All) {
			c.Next()
			return
		}
		ok := subPermissions.Contains(permissions...)
		if ok {
			c.Next()
		} else {
			response.ErrorAuthorizationFail(c, "")
		}
	}
}

func CheckPermission(permission string, subject AuthSubject) gin.HandlerFunc {
	return func(c *gin.Context) {
		if subject == nil {
			response.ErrorAuthorizationFail(c, "")
			return
		}
		subPermissions := subject.GetPermissions(c)
		if subPermissions.Contains(consts.Permission_All) {
			c.Next()
			return
		}
		ok := subPermissions.Contains(permission)
		if ok {
			c.Next()
		} else {
			response.ErrorAuthorizationFail(c, "")
		}
	}
}
